#include <gl\glew.h>


#include <iostream>
#include <fstream>
#include <SDL.h>
#include "SDL_image.h"

#include<AlphaTools.h>
#include"GameApp.h"

using namespace std;

#if _DEBUG
#pragma comment(linker, "/subsystem:\"console\" /entry:\"WinMainCRTStartup\"")
#endif

GameComponent* g;// = new GameApp();

void sdlFatalErr(char *message)
{
    cout << message << " " << SDL_GetError();
    SDL_Quit();
    exit(1);
}

void cleanUp(void)
{	
}

// Set up rendering context, call by reference
void setupRC(SDL_WindowID &window, SDL_GLContext &context)
{
    if (SDL_Init(SDL_INIT_VIDEO) < 0) // Initialize video
	{
        sdlFatalErr("Unable to initialize SDL"); 
	}

    // Request an OpenGL 3.0 context.
    // Not able to use SDL to choose profile (yet), should default to core profile
    // on 3.2 or later
    // If you request a context not supported by your drivers, no OpenGL context
    // will be created.
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
 
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);  // double buffering on

	// Turn on x4 multisampling anti-aliasing (MSAA)
	SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
	SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4);
 
    // Create 800x600 window
    window = SDL_CreateWindow("Omega Engine Demo", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);	
	if(!window) // Check window was created OK
	{
        sdlFatalErr("Unable to create window");
	}
 
    context = SDL_GL_CreateContext(window); // Create opengl context and attach to window

	SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); //8 bit alpha buffering.

    SDL_GL_SetSwapInterval(1); // set swap buffers to sync with monitor's vertical refresh rate

}

void init(void)
{
	((GameApp*)g)->init();
}

void render(const SDL_WindowID &window)
{
	glEnable(GL_BLEND);
	glEnable(GL_DEPTH_TEST);
	glClearColor(0.0, 0.0,0.0, 1.0); // set background colour
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear window
	((GameApp*)g)->render();
	SDL_GL_SwapWindow(window); // swap buffers
}

// Program entry point - SDL manages the actual WinMain entry point for us
int main(int argc, char *argv[])
{
	SDL_Event sdlEvent;	// variable to detect SDL events
	bool running = true;
    SDL_WindowID hWindow; // window handle
	SDL_GLContext glContext;

	setupRC(hWindow, glContext);

	glewExperimental = true;
	GLenum err = glewInit();
	// Required on Windows... init GLEW to access OpenGL beyond 1.1
	// remove on other platforms
	if (GLEW_OK != err)
	{	// glewInit failed, something is seriously wrong.
		cout << "glewInit failed, aborting." << endl;
		exit (1);
	}
	cout << "Using GLEW Version: " << glewGetString(GLEW_VERSION) << endl;
	cout << "OpenGL: OpenGL version " << glGetString(GL_VERSION) << " supported" << endl << endl;
	g = new GameApp();
	init();

	while (running)		// the event loop
	{
		while (SDL_PollEvent(&sdlEvent)) 
		{
			((GameApp*)g)->keyBoardHandler(sdlEvent);
			((GameApp*)g)->captureMouse(sdlEvent);
			((GameApp*)g)->reshapeWindow(sdlEvent);
			if (sdlEvent.type == SDL_QUIT)
				running = false;
		}
		((GameApp*)g)->update();	
		render(hWindow);
	}

	//Clean Up
	cleanUp();
    SDL_GL_DeleteContext(glContext);
    SDL_DestroyWindow(hWindow);
    SDL_Quit();
    return 0;
}